package com.yuan.ayuancity.controller.common;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.yuan.ayuancity.entity.Infos;
import com.yuan.ayuancity.entity.Orders;
import com.yuan.ayuancity.mapper.OrdersMapper;
import com.yuan.ayuancity.service.InfosService;
import com.yuan.ayuancity.service.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 *    支付宝沙箱支付功能
 *    需要内网穿透返回回调函数
 * </p>
 *
 * @author asuyuan
 * @since 2023/5/10
 */
@Controller
@RequestMapping("/city/v1")
public class PayController {


    //appid
    private final String APP_ID = "2021000122688671";
    //应用私钥
    private final String APP_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCThw/f3UgznWV" +
            "FdONlixK+uVvXo8Sp/bfejUzAFwAMA6160GKWuPjgKFBYYjQMcgJUcgO5O/9lSNNDXcgc4exrI7U0wNWq3UHv3acRRhH/nUE0NL" +
            "T3m275KiD+KqX5WcbDZPWPmqFRF/FUysr7v7r6xq9ooLaeaucoGC++npGZkv35a3KoaYHPXGrUbBEYnxcK463giUQGFZ8e36GROv" +
            "nXpIK47A4ogxm42PWyu4+rsk/CLSu6dhOoiKSypQDqHpYRHbfxbtU+T+L7P2vxGTS1xQi0RLDF42RPx8IuM4iS7faQqwzcK6kDPPJEmop" +
            "CEm3EPXLxN/ZkpFn7D3XXTndPAgMBAAECggEAI2AYo2KpZI8ScKRFvtypYwiJiFzh1K1dQMV7KPia70aWe8OqUGAMdZvVIEx0FKPmAR/R2sI" +
            "TTNM4rYe4a4yVJ1/JnNu8oJsrq3voCtFVkYjA0Obumg0wgBjlDm1lnTQ04De+VnAKzKpEGUQDhniEOowYFaur/rK9uTSLhlb5rOxeiJXG/YLM" +
            "QNbZxKnNhQtVbynQi7az9ot65DM+xmKBU9JycJ+PhuntJMZ6LDJit4E1eq6LiJyEBKlydgfdnvEdnHsA2aExPvU9zTUz+TBAD2kO1GlsImUNs" +
            "NZO98oIbrgWP4VbhdJvgH20oUbX9Bgqd+Xef0TP08Rxqr+oQDfWKQKBgQDrOJ3GWrAqVHLaedU4jX/msBbx5erShFaF2bV0TP7tEIb8KKEZR0" +
            "IACCtcFS6mkZcdt6aXaBUlRNS0FVrazvfyu4tSlpcwGWZuzWg91O97UtWQKTcmkOjXFXOLZikujfpqVstD0h52rcVuIxA+8KyTBIvzd9dx8OCg" +
            "1uIjtB3ZKwKBgQCgj08OdqX5/yuo1GGr+d1ileFQQoDdnuHjLPzoJ0QeRKJ/fhi/cL879AchtXSO44kOf2xuHmmFrGHNiK1gwPkMk0kJMOkot6m" +
            "ApmdtNjUTCWtFsaPjpJiMcpyLps74aaYSfvvFZ1RpdgLgZhkKjJxV/8onoqKOYTjPU0yZFUsAbQKBgQCj2BH+YpknQx+lkwu0ksuukqXI5ZAGB" +
            "2yFW7qLQj6oPsTnzB07EGmmwAoD4DVYjT0n1A7UlAl2plVLAz0AAP6xM3W+l2rEdEznjWi4+SO/UVm1SyBBWtr1RtnvFcBFz1vIyqBXo3rYy/4j" +
            "04Szcs2isp4Rfz6w/UpafpOSrxnDdQKBgCfm1Y/TnrX9Wz1O4qMZqpIYi3Elxd7N4HdTs9qB/6TCC9xBWycgfvYIVEllTf1AwMvwkOLg/fpxd7Db" +
            "mbLk4j/kzo7RL/CljCNjt2plwVTkz1r3pbIqMpsc1JjEMMV9g/8uvaU2Y7z9zgM0fF6pySR6OCQXf+yAbtzfZ7bXmtcVAoGBAMIShbq1/nhpHL62" +
            "G6Rw98lrpIQm/lTbCD2Qry7jlDb2S6+LCe4x+mzibrx+qASrf" +
            "dE2RLVRnMek3R58SkvucMSQUnqbhe/FQqOtd16fm42bP4EcTUPkyFmvDsYMgmIQ8uVhePaJKmG03wr9qIuUr+0JY5bd3TEWAjixl7cIHw3F";
    // 支付宝公钥
    private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArAKvLd8+8UTS2Pgb7suR7SjiNmau4UeIJzWVp" +
            "ZSoln4AomVx1BV23K/Uf0ipqTOHk9KtfhZagkJfb1b4TwJqFuQzVIW8OhxMWfU61KXaVlksIN0eix9dnnRHTxvsXP4ZghncFAmypwiI1zLCx0e6o86wi" +
            "ij+QMaMUE1Y+pSeoCkMCIQIEcwC8+nus1CsC5psCqjGedl/WTWhRAnK4q+PIvcRm" +
            "Dqg3k6tmSQafZ4pdaU8/csPpaENlgzeLSdQzUuMvAdUq3KtNFRang9rv5NqygYP7wktRrbOfM8q74v9JUHQI" +
            "+oGm75LeZlWG579FrENtsOFZUAc1r07jwNUFjPhBQIDAQAB";

    private final String CHARSET = "UTF-8";
    //这是沙箱接口路径,正式路径为https://openapi.alipay.com/gateway.do
    private final String GATEWAY_URL ="https://openapi.alipaydev.com/gateway.do";
    private final String FORMAT = "JSON";
    //签名方式
    private final String SIGN_TYPE = "RSA2";
    //支付宝异步通知路径,付款完毕后会异步调用本项目的方法,必须为公网地址
    private final String NOTIFY_URL = "5a3c251167.zicp.fun:39128";
    //支付宝同步通知路径,也就是当付款完毕后跳转本项目的页面,可以不是公网地址
    private final String RETURN_URL = "http://localhost:8080/city/v1/returnUrl";

    @Autowired
    private InfosService infosService;
    @Resource
    private OrdersMapper ordersMapper;


    //商品页面支付
    @ResponseBody
    @GetMapping("/pay/alipay")
    public String alipay(@RequestParam("infoId") Integer infoId,
                         @RequestParam("infoPrice") String infoPrice,
                         @RequestParam("userId") String userId) throws AlipayApiException {


        //生成订单号（支付宝的要求？）
        String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String user = UUID.randomUUID().toString().replace("-","").toUpperCase();
        String OrderNum = time+user;

        //========添加数据库======
        //查询商品信息
        final Infos infos = infosService.selectInfosByInfoId(Long.parseLong(infoId+""));
        Orders orders=new Orders();
        orders.setAlipayNo(OrderNum);
        orders.setCreateTime(new Date());
        orders.setInfoId(infoId+"");
        orders.setUserId(Integer.parseInt(userId));
        orders.setTotalPrice(new BigDecimal(infoPrice));
        orders.setInfoTitle(infos.getInfoTitle());
        ordersMapper.insert(orders);//mybatis插入：id会自动填充到order
        //======================

        //调用封装好的方法（给支付宝接口发送请求）
        return sendRequestToAlipay( orders,"YuanCity-"+infoId);
    }


    //个人中心的支付
    @ResponseBody
    @GetMapping("/pay/alipay2")
    public String alipay(@RequestParam("ordersId") String ordersId) throws AlipayApiException {

        final Orders orders = ordersMapper.selectById(ordersId);

        //调用封装好的方法（给支付宝接口发送请求）
        return sendRequestToAlipay( orders,"YuanCity-"+orders.getInfoId());
    }








    //支付宝官方提供的接口
    private String sendRequestToAlipay(Orders order,String subject) throws AlipayApiException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL,APP_ID,APP_PRIVATE_KEY,FORMAT,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);


        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(RETURN_URL+"?orderId="+order.getId());//可以存在session也能获取到
        alipayRequest.setNotifyUrl(NOTIFY_URL);


        //查询商品信息
        final Infos infos = infosService.selectInfosByInfoId(Long.parseLong(order.getInfoId()));
        //商品描述（可空）
        String body=infos.getInfoTitle()+"-"+infos.getInfoContent();
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + order.getAlipayNo() + "\","
                + "\"total_amount\":\"" + order.getTotalPrice() + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\""
                +  "}"
             );

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        if (alipayClient.pageExecute(alipayRequest).isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }

        return result;
    }

    @RequestMapping("/returnUrl")
    public String returnUrlMethod(HttpServletRequest request , Model model) throws AlipayApiException, UnsupportedEncodingException {
        System.out.println("=================================同步回调=====================================");

        // 获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        System.out.println(params);//查看参数都有哪些
        //验证签名（支付宝公钥）
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE); // 调用SDK验证签名
        //验证签名通过
        if(signVerified){
            // 商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 支付宝交易流水号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 付款金额
            float money = Float.parseFloat(new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"));
            //订单id
            String orderId = new String(request.getParameter("orderId").getBytes("ISO-8859-1"), "UTF-8");

            System.out.println("商户订单号="+out_trade_no);
            System.out.println("支付宝交易号="+trade_no);
            System.out.println("付款金额="+money);
            System.out.println("订单id="+orderId);

            //===========数据库的操作======
                 Orders orders = ordersMapper.selectById(orderId);
                 orders.setState("付款成功");
             int update = ordersMapper.updateById(orders);
            //===========================
            //跳转到提示页面（成功或者失败的提示页面）
            model.addAttribute("payflag",1);
            model.addAttribute("paymsg","付款成功");

            return "redirect:/view/html/itemDetail.html?infoId="+orders.getInfoId();
        }else{
            //订单id
            String orderId = new String(request.getParameter("orderId").getBytes("ISO-8859-1"), "UTF-8");
            final Orders orders = ordersMapper.selectById(orderId);
            //===========数据库的操作======
            //TODO:虽然签名验证失败了，但我还是给他付款成功了，因为支付宝签名老是要更新，懒得去生产签名了
            orders.setState("付款成功");
            int update = ordersMapper.updateById(orders);
            //===========================

            //-------------------------------------------------------------------
            //跳转到提示页面（成功或者失败的提示页面）
                model.addAttribute("payflag",0);
            model.addAttribute("paymsg","付款失败");
            return "redirect:/view/html/itemDetail.html?infoId="+orders.getInfoId();
        }


//      jyllcb2061@sandbox.com

    }


}
